﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cosmetic.DataEntity;
using System.Collections;

namespace Cosmetic.Logic
{
	/// <summary>
	/// Comment manager class
	/// </summary>
	public class CommentManager : LogicBase
    {
        private TagManager m_TagManager = new TagManager();
        //private ProductManager m_ProductManager = new ProductManager();


        /// <summary>
        /// get comment by product and take top n Product
        /// </summary>
        /// <param name="aProduct"></param>
        /// <param name="Count"></param>
        /// <returns></returns>
        public List<Comment> GetAllCommentByProduct(Product aProduct)
        {
            List<Comment> lc = this.GetCommentByProduct(aProduct).ToList();
            return lc;
        }

		/// <summary>
		/// Insert a new Comment into database
		/// </summary>
		/// <param name="aComment">new Comment</param>
		public void Insert(Comment aComment)
		{
			m_CosmeticDC.Comments.InsertOnSubmit(aComment);
			m_CosmeticDC.SubmitChanges();
			//this.BuildTag(aComment);
		}

        public void InsertBySql(Comment aComment)
        {
            string Sql = "insert into Comment(CommentId, ProductId, UserId, Content, Score, IsSample, CreateTime, PurchaseChannelsCategoryId, BigCategory) values('"+aComment.CommentId.ToString()+"','"+aComment.ProductId.ToString()+"','"+aComment.UserId.ToString()+"','"+aComment.Content+"','"+aComment.Score.ToString()+"','"+"1"+"','"+aComment.CreateTime.ToString()+"','"+aComment.PurchaseChannelsCategoryId.ToString()+"','"+aComment.BigCategory.ToString()+"'"+")";
            m_CosmeticDC.ExecuteCommand(Sql);
        }

		/// <summary>
		/// Delete Comment
		/// </summary>
		/// <param name="aComment">The Comment want delete</param>
		public void Delete(Comment aComment)
		{
			string[] theTags			= aComment.Tag.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
			foreach (string theTagName in theTags)
			{
				Tag theTag				= this.m_TagManager.GetTagByName(theTagName, TagManager.ETagCategory.Product);
				m_TagManager.MinusCount(theTag);

                ProductManager.ProductTagMinusCount(m_CosmeticDC, theTag.TagId, aComment.ProductId);
			}
            Comment toBeDelete = m_CosmeticDC.Comments.Where(c => c.CommentId == aComment.CommentId).Single();
            m_CosmeticDC.Comments.DeleteOnSubmit(toBeDelete);
			m_CosmeticDC.SubmitChanges();
		}

		/// <summary>
		/// update comment
		/// </summary>
		/// <param name="aComment">comment</param>
		public void Update(Comment aComment)
		{
            this.RebuildTag(aComment);
            m_CosmeticDC.SubmitChanges();
		}

		/// <summary>
		/// create tag record or add tag's count,  and create comment,tag relationship record
		/// </summary>
		/// <param name="aComment">comment</param>
		private void BuildTag(Comment aComment)
		{
			string[] theTags	= aComment.Tag.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);

			theTags				= theTags.Distinct().ToArray();

			foreach (string theTagName in theTags)
			{
				Tag theTag		= this.m_TagManager.Insert(theTagName, TagManager.ETagCategory.Product);

                ProductManager.ProductTagAddCount(m_CosmeticDC, theTag.TagId, aComment.ProductId);
			}
			m_CosmeticDC.SubmitChanges();
		}
		/// <summary>
		/// minus count or delete old tag record,  delete comment, tag relationship record.
		/// create new tag's record or add count, create new relationship reocord
		/// </summary>
		/// <param name="aComment">comment</param>
		private void RebuildTag(Comment aComment)
		{
			Comment theSourceComment	= this.GetCommentById(aComment.CommentId);
			string[] theTags			= aComment.Tag.Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
			foreach (string theTagName in theTags)
			{
				Tag theTag				= this.m_TagManager.GetTagByName(theTagName, TagManager.ETagCategory.Product);
				m_TagManager.MinusCount(theTag);

                ProductManager.ProductTagMinusCount(m_CosmeticDC, theTag.TagId, aComment.ProductId);
			}
			this.BuildTag(aComment);
		}





		/// <summary>
		/// Get Comment by Comment Id
		/// </summary>
		/// <param name="aCommentId">Comment Id</param>
		/// <returns>Comment</returns>
		public Comment GetCommentById(Guid aCommentId)
		{
			return m_CosmeticDC.Comments.Single(theComment => theComment.CommentId == aCommentId);
		}

        /// <summary>
        /// get comment by product and take top n Product
        /// </summary>
        /// <param name="aProduct"></param>
        /// <param name="Count"></param>
        /// <returns></returns>
        public List<Comment> GetCommentByProduct(Product aProduct, int Count)
        {
            List<Comment> lc = this.GetCommentByProduct(aProduct).Take(Count).ToList();
            return lc;
        }



		/// <summary>
		/// get comment by product
		/// </summary>
		/// <param name="aProduct">product</param>
		/// <returns>comment of the product</returns>
		public List<Comment> GetCommentByProduct(Product aProduct)
		{
            List<Comment> lc = GetCommentByProduct(aProduct.ProductId);
            return lc;
		}
		/// <summary>
		/// get comment by product id
		/// </summary>
		/// <param name="aProductId">product id</param>
		/// <returns>comment of the product</returns>
		public List<Comment> GetCommentByProduct(Guid aProductId)
		{
			var result = (from theComment in m_CosmeticDC.Comments 
						where theComment.ProductId == aProductId
						orderby theComment.CreateTime descending
			            select theComment).ToList();
            return result;
		}

        //public IEnumerable GetCommentTop5()
        //{
        //    var result = from comment in m_CosmeticDC.Comments
        //                 //where comment.BigCategory == CategoryId
        //                 select new
        //                 {
        //                     ProductID = comment.ProductId.ToString(),
        //                     ProductName = comment.Product.Name,
        //                     ProductBrand = comment.Product.Brand.Name,
        //                     ProductImage = comment.Product.PictureUrl,
        //                     UserImage = getUserImage(comment.UserId),
        //                     UserName = getUserName(comment.UserId),
        //                     UserArea = getUserArea(comment.UserId),
        //                     CommentContent = comment.Content,
        //                     CommentScore = comment.Score
        //                 };
        //    return result.Take(5);
        //}

		/// <summary>
		/// get comment by tag
		/// </summary>
		/// <param name="aTag">the specify tag</param>
		/// <returns>comment list</returns>
		public List<Comment> GetCommentByTag(Tag aTag)
		{
			return (from theComment in m_CosmeticDC.Comments
						join theCommmentTag in m_CosmeticDC.CommentTags on theComment.CommentId equals theCommmentTag.CommentId
						where theCommmentTag.TagId == aTag.TagId
						select theComment).ToList();
		}

		/// <summary>
		/// get all comment
		/// </summary>
		/// <returns>comment list</returns>
		public List<Comment> GetAll()
		{
			return m_CosmeticDC.Comments.ToList();
		}

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public List<Category> GetBigCategoryList()
        {
            string TopCategoryString = "Category_L";

            var supCategory = (from theCategory in m_CosmeticDC.Categories
                               where theCategory.Name == TopCategoryString
                               select theCategory.CategoryId).Single();
            var result = from theBigCategory in m_CosmeticDC.Categories
                         where theBigCategory.SupCategoryId == supCategory
                         && theBigCategory.CategoryId != theBigCategory.SupCategoryId
                         select theBigCategory;

            List<Category> resultlist = result.ToList();
            return resultlist;
        }


        /// <summary>
        /// 获得该大类所有的评论:服饰,美妆,家具,电器,杂货,食品,日用品
        /// </summary>
        /// <returns></returns>
        //public IList GetCommentByBigCategory(Guid CategoryId)
        //{
        //    //ProductName 产品名
        //    //品牌
        //    //userimage
        //    //username
        //    //userarea
        //    //Product image
        //    //推荐度，评语

        //    var result = from comment in m_CosmeticDC.Comments
        //                 where comment.BigCategory == CategoryId
        //                 select new 
        //                 {
        //                    ProductID          =comment.ProductId.ToString(),
        //                    ProductName     = comment.Product.Name,
        //                    ProductBrand    = comment.Product.Brand.Name,
        //                    ProductImage    = comment.Product.PictureUrl,
        //                    UserImage       = getUserImage(comment.UserId),
        //                    UserName        = getUserName(comment.UserId),
        //                    UserArea        = getUserArea(comment.UserId),
        //                    CommentContent  = comment.Content,
        //                    CommentScore    = comment.Score
        //                 };
        //    return result.ToList();
        //}


        public Guid GetProductsBigCategory(Guid ProductId)
        {
            Guid categoryId = (from gpt in m_CosmeticDC.Products
                         where gpt.ProductId == ProductId
                         select gpt.ProductCategoryId).Single();
            Guid supCategoryId = (from cates in m_CosmeticDC.Categories
                                  where cates.CategoryId==categoryId
                                  select cates.SupCategoryId).Single();

            while(categoryId != supCategoryId)
            {
                var result = (from cates in m_CosmeticDC.Categories
                             where cates.CategoryId==supCategoryId
                             select cates.SupCategory).Single();

                categoryId  = result.CategoryId;
                supCategoryId = result.SupCategoryId;
            }
            return categoryId;
        }

        //public IList GetNewestCommentByBigCategory()
        //{
        //    var result = from comment in m_CosmeticDC.Comments
        //                 orderby comment.CreateTime descending
        //                 select new
        //                 {
        //                     ProductID      = comment.ProductId.ToString(),
        //                     ProductName = comment.Product.Name,
        //                     ProductBrand = comment.Product.ProductCategory.Name.Remove(0,4),
        //                     ProductImage = comment.Product.PictureUrl,
        //                     UserImage = getUserImage(comment.UserId),
        //                     UserName = getUserName(comment.UserId),
        //                     UserArea = getUserArea(comment.UserId),
        //                     CommentContent = comment.Content,
        //                     CommentScore = comment.Score,
        //                     Commentid=comment.CommentId
        //                 };
        //    return result.ToList();
        //}


        //private string getUserArea(Guid UserId)
        //{
        //    var result = from user in m_CosmeticDC.UserInfos
        //                 where user.UserId == UserId
        //                 select user.Province;

        //    return result.Single();
        //}

        //private string getUserName(Guid UserId)
        //{
        //    var result = from user in m_CosmeticDC.Users
        //                 where user.UserId == UserId
        //                 select user.UserName;
        //    return result.Single();
        //}


        //private string getUserImage(Guid UserId)
        //{
        //    var result = from user in m_CosmeticDC.Users
        //                 where user.UserId == UserId
        //                 select user.PictureUrl;
        //    return result.Single();
        //}

        public IEnumerable GetCommentList()
        {
            var result = from comm in m_CosmeticDC.Comments
                         join prot in m_CosmeticDC.Products
                         on comm.ProductId equals prot.ProductId
                         orderby comm.CreateTime descending
                         select new
                         {
                             ProductId = prot.ProductId,
                             ProductName = prot.Name,
                             ProductCode = prot.ProductCode,
                             Comment = comm.Content,
                             CreateTime = comm.CreateTime
                         };
            return result;
        }
        


	}
}
